// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

namespace Microsoft.Samples.Commerce.Order.CommerceEntities
{
    using System;
    using Microsoft.Commerce.Contracts;

    /// <summary>
    /// Representation of the catalog product or category.
    /// </summary>
    public class CatalogEntity : ICommerceEntity
    {
        /// <summary>
        /// defines the model name for this commerce entity
        /// </summary>
        public const string ModelNameDefinition = "CatalogEntity";

        /// <summary>
        /// The commerce entity.
        /// </summary>
        private CommerceEntity commerceEntity;

        /// <summary>
        /// Initializes a new instance of the <see cref="CatalogEntity"/> class.
        /// </summary>
        public CatalogEntity()
        {
            this.commerceEntity = new CommerceEntity(CatalogEntity.ModelNameDefinition);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CatalogEntity"/> class.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        public CatalogEntity(CommerceEntity commerceEntity)
        {
            this.commerceEntity = commerceEntity;
        }

        #region ICommerceEntity Members

        /// <summary>
        /// Gets or sets the name of the model.
        /// </summary>
        /// <value>The name of the model.</value>
        public string ModelName
        {
            get
            {
                return this.commerceEntity.ModelName;
            }

            set
            {
                this.commerceEntity.ModelName = value;
            }
        }

        /// <summary>
        /// Gets or sets the properties.
        /// </summary>
        /// <value>The properties.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommercePropertyCollection Properties
        {
            get
            {
                return this.commerceEntity.Properties;
            }

            set
            {
                this.commerceEntity.Properties = value;
            }
        }

        #endregion

        /// <summary>
        /// Gets or sets the unique identifier of the commerce entity
        /// </summary>
        /// <value>The CommerceEntity property id.</value>
        /// <remarks>This is a required property.</remarks>
        public string Id
        {
            get { return this.commerceEntity.GetPropertyValue(CommerceEntity.PropertyName.Id) as string; }
            set { this.commerceEntity.SetPropertyValue(CommerceEntity.PropertyName.Id, value); }
        }

        /// <summary>
        /// Gets or sets the unique identifier of the parent of the commerce entity
        /// </summary>
        /// <value>The parent id.</value>
        /// <remarks>This is optional and will only present if the parent supports this property.</remarks>
        public string ParentId
        {
            get { return this.commerceEntity.GetPropertyValue(CommerceEntity.PropertyName.ParentId) as string; }
            set { this.commerceEntity.SetPropertyValue(CommerceEntity.PropertyName.ParentId, value); }
        }

        /// <summary>
        /// Gets or sets the date the commerce entity was created.
        /// </summary>
        /// <value>The date created.</value>
        public DateTime? DateCreated
        {
            get { return this.commerceEntity.GetPropertyValue(CommerceEntity.PropertyName.DateCreated) as DateTime?; }
            set { this.commerceEntity.SetPropertyValue(CommerceEntity.PropertyName.DateCreated, value); }
        }

        /// <summary>
        /// Gets or sets the date the commerce entity was modified.
        /// </summary>
        /// <value>The date modified.</value>
        public DateTime? DateModified
        {
            get { return this.commerceEntity.GetPropertyValue(CommerceEntity.PropertyName.DateModified) as DateTime?; }
            set { this.commerceEntity.SetPropertyValue(CommerceEntity.PropertyName.DateModified, value); }
        }

        /// <summary>
        /// Gets or sets the modified by user.
        /// </summary>
        /// <value>The user that last modfied the commerce entity.</value>
        public string ModifiedBy
        {
            get { return this.commerceEntity.GetPropertyValue(CommerceEntity.PropertyName.ModifiedBy) as string; }
            set { this.commerceEntity.SetPropertyValue(CommerceEntity.PropertyName.ModifiedBy, value); }
        }

        /// <summary>
        /// Gets or sets the type of the catalog entity.
        /// </summary>
        /// <value>The type of the catalog entity.</value>
        public int? CatalogEntityType
        {
            get
            {
                return (int?)this.commerceEntity.GetPropertyValue(CatalogEntity.PropertyName.CatalogEntityType);
            }
            
            set
            {
                this.commerceEntity.SetPropertyValue(CatalogEntity.PropertyName.CatalogEntityType, value ?? null);
            }
        }

        /// <summary>
        /// Gets or sets the DisplayName property for this catalog item.
        /// </summary>
        /// <value>The display name.</value>
        /// <remarks>This is an optional property.</remarks>
        public string DisplayName
        {
            get
            {
                return this.commerceEntity.GetPropertyValue(PropertyName.DisplayName) as string;
            }
         
            set
            {
                this.commerceEntity.SetPropertyValue(PropertyName.DisplayName, value);
            }
        }

        /// <summary>
        /// Gets or sets the catalog id.
        /// </summary>
        /// <value>the id of the catalog</value>
        public string CatalogId
        {
            get
            {
                return this.commerceEntity.GetPropertyValue(PropertyName.CatalogId) as string;
            }

            set
            {
                this.commerceEntity.SetPropertyValue(PropertyName.CatalogId, value);
            }
        }

        /// <summary>
        /// Gets or sets the list price.
        /// </summary>
        /// <value>The list price.</value>
        public decimal? ListPrice
        {
            get
            {
                return (decimal?)this.commerceEntity.GetPropertyValue(PropertyName.ListPrice);
            }

            set
            {
                this.commerceEntity.SetPropertyValue(PropertyName.ListPrice, value ?? null);
            }
        }

        /// <summary>
        /// Gets or sets the name of product or category definition used to create this item.
        /// </summary>
        /// <value>The name of the definition.</value>
        /// <remarks>This is a required property.</remarks>
        public string DefinitionName
        {
            get
            {
                return this.commerceEntity.GetPropertyValue(PropertyName.DefinitionName) as string;
            }

            set
            {
                this.commerceEntity.SetPropertyValue(PropertyName.DefinitionName, value);
            }
        }

        /// <summary>
        /// Gets or sets the associated Commerce entity
        /// </summary>
        protected CommerceEntity CommerceEntity
        {
            get
            {
                return this.commerceEntity;
            }

            set
            {
                this.commerceEntity = value;
            }
        }

        /// <summary>
        /// Toes the commerce entity.
        /// </summary>
        /// <returns>The commerce entity.</returns>
        public CommerceEntity ToCommerceEntity()
        {
            return this.commerceEntity;
        }

        /// <summary>
        /// Names of the properties exposed by this commerce entity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public class PropertyName 
        {
            /// <summary>
            /// The name of the DateCreated property for a CommerceEntity.
            /// </summary>
            public const string DateCreated = "DateCreated";

            /// <summary>
            /// The name of the DateModified property for a CommerceEntity.
            /// </summary>
            public const string DateModified = "DateModified";

            /// <summary>
            /// The name of the Id property for a CommerceEntity.
            /// </summary>
            public const string Id = "Id";

            /// <summary>
            /// The name of the ModifiedBy property for a CommerceEntity.
            /// </summary>
            public const string ModifiedBy = "ModifiedBy";

            /// <summary>
            /// The name of the ParentId property for a CommerceEntity.
            /// </summary>
            public const string ParentId = "ParentId";

            /// <summary>
            /// The CatalogEntityType property for a CommerceEntity.
            /// </summary>
            public const string CatalogEntityType = "CatalogEntityType";
            
            /// <summary>
            /// The DefinitionName property for a CommerceEntity.
            /// </summary>
            public const string DefinitionName = "DefinitionName";
            
            /// <summary>
            /// The DisplayName property for a CommerceEntity.
            /// </summary>
            public const string DisplayName = "DisplayName";
            
            /// <summary>
            /// The ListPrice property for a CommerceEntity.
            /// </summary>
            public const string ListPrice = "ListPrice";
            
            /// <summary>
            /// The CatalogId property for a CommerceEntity.
            /// </summary>
            public const string CatalogId = "CatalogId";
        }
    }
}
